/*  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef luge_pad_hh
#define luge_pad_hh

#include "luge-util.hh"
#include <gegl.h>
#include <lualib.h>
#include <lauxlib.h>
#include <lua.h>
#include <string>
#include <sstream>

namespace luge {

/**
 * an intermediate object for creating pads, this allows to
 * use a syntax like node.input from within lua.
 * a pad is essentially a reference to a node/name pair.
 */
struct pad
{
  pad (GeglNode *node, const std::string &name);
  pad (const pad &that);
  ~pad ();
  /**
   * return a string representation for debugging output.
   */
  std::string to_string () const;
  /**
   * the node this pad references. The reference count
   * for the node is increased.
   */
  GeglNode *const node;
  const std::string name;
};

/**
 * return true, iff the property prop of the node represents
 * output pad.
 */
bool is_io_prop (GeglNode *node, const std::string &prop);
/**
 * return true, iff the property prop of the node represents
 * an output pad.
 */
bool is_output_prop (GeglNode *node, const std::string &prop);
/**
 * return true, iff the property prop of the node represents an
 * input pad.
 */
bool is_input_prop (GeglNode *node, const std::string &prop);

/**
 * get the output pad for the nodes pad named pad. For output pads
 * a reference to the pad itself is returned, for input pads the connected
 * producer (or an empty pad) is returned.
 */
pad get_output_pad (GeglNode *node, const std::string &prop);

/**
 * return a reference to the pad at the index idx.
 * If the argument at the index is a node, returns its default output
 * pad (which is called 'output').
 * A copy of the actual pad is returned.
 */
pad to_pad (lua_State *ls, int idx);

/**
 * push a copy of pad onto the lua stack.
 */
void push_pad (lua_State *ls, const pad &pad);

/**
 * return true, iff the object at index idx is a pad.
 */
bool is_pad (lua_State *ls, int idx);

/**
 * initialize the pad-datatype.
 */
void init_pad (lua_State *ls);

} /* namespace luge */
#endif
